/*
 * Copyright:  2018 smarabbit studio.
 *
 *  Licensed under the Confluent Community License; you may not use this file
 *  except in compliance with the License.  You may obtain a copy of the License at
 *
 *  http://www.confluent.io/confluent-community-license
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *  WARRANTIES OF ANY KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations under the License.
 *
 *  @作   者： 黄开晖 (117227773@qq.com)
 *  @日   期:  2020年8月25日
 */
package com.massyframework.beanskin.launcher.deploying;

import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.net.URL;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.nio.file.Path;
import java.util.Map;

import com.massyframework.beanskin.framework.Framework;
import com.massyframework.beanskin.util.IOUtils;
import com.massyframework.beanskin.util.localstore.LocalStore;

/**
 * 缺省的本地存储工厂
 * @author huangkh
 *
 */
public final class DefaultLocalStoreFactory {

	/**
	 * 
	 */
	public DefaultLocalStoreFactory() {
	}

	public LocalStore createLocalStore(Map<String, String> configuration) {
		Path root = this.getWorkDirectory();
		
		
		
		
		FileLock lock = this.createFileLock(root);
		
		if (lock == null) {
			throw new AnotherProcessIsRuningException();
		}
		
		String text = configuration.getOrDefault(Framework.STORAGE_CLEAN, 
				Framework.STORGE_CLEAN_NONE);
		boolean clean = Framework.STORGE_CLEAN_ONFIRSTCLEAN.equals(text);
		
		Path frontendPath = null;
		text = configuration.get(Framework.STORAGE_FRONTEND);
		if (text != null) {
			frontendPath = new File(text).toPath();
		}else {
			frontendPath = root.resolve("frontend");
		}
		
		Path fragmentPath = null;
		text = configuration.get(Framework.STORAGE_FRAGMENT);
		if (text != null) {
			fragmentPath = new File(text).toPath();
		}else {
			fragmentPath = root.resolve("fragment");
		}
		return new DefaultLocalStore(root, fragmentPath, frontendPath, lock, clean);
	}

	/**
	 * 工作目录
	 * @return {@link Path}
	 */
	protected Path getWorkDirectory() {
		URL url = this.getClass().getClassLoader().getResource("/");
		if (url == null) {
			url = this.getClass().getClassLoader().getResource("");
		}
		String path = url.getPath();	
		File file = new File(path);
		File parent = file.getParentFile();
		return new File(parent, "workspace").toPath();
	}
		
	/**
	 * 创建文件锁
	 * @param root {@link Path}
	 * @return {@link FileLock}
	 */
	protected FileLock createFileLock(Path root) {
		File rootDir = root.toFile();
		if (!rootDir.exists()) {
			rootDir.mkdirs();
		}
		
		File lockFile = new File(rootDir,"lockFile");
		if (!lockFile.exists()) {
			try {
				lockFile.createNewFile();
			}catch(IOException e) {
				
			}
		}
		

		RandomAccessFile out = null;
		FileChannel channel = null;
		try {
			out = new RandomAccessFile(lockFile, "rw");
            channel = out.getChannel();
            return channel.tryLock();
		}catch(IOException e) {
			return null;
		}finally {
			IOUtils.close(channel);
			IOUtils.close(out);
			
		}
	}

	@Override
	public String toString() {
		return "DefaultLocalStoreFactory";
	}
}
